home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Storage / Bento / CM / TOCIO.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  31.8 KB  |  610 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        TOCIO.h
  3.  
  4.     Contains:    Container Manager TOC I/O Interfaces
  5.  
  6.     Written by:    Ira L. Ruben
  7.  
  8.     Owned by:    Ed Lai
  9.  
  10.     Copyright:    © 1992 - 1996 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     Change History (most recent first):
  13.  
  14.          <2>     1/15/96    TJ        Cleaned Up
  15.          <2>     8/26/94    EL        #1182275 extra parameter in cmWriteTOC to
  16.                                     truncate free space.
  17.          <4>      2/3/94    EL        Bento File names are now eight chars or
  18.                                                     less.
  19.          <3>    11/23/93    EL        When updating save TOC data so that TOC
  20.                                                     don't need to be read twice.
  21.          <2>    10/21/93    EL        In cmReadTOC, allow restriction of kind of
  22.                                                     entry read.
  23.  
  24.     To Do:
  25. */
  26.  
  27. /*---------------------------------------------------------------------------*
  28.  |                                                                           |
  29.  |                              <<< TOCIO.h >>>                              |
  30.  |                                                                           |
  31.  |                   Container Manager TOC I/O Interfaces                    |
  32.  |                                                                           |
  33.  |                               Ira L. Ruben                                |
  34.  |                                 10/01/92                                  |
  35.  |                                                                           |
  36.  |                     Copyright Apple Computer, Inc. 1992-1994              |
  37.  |                           All rights reserved.                            |
  38.  |                                                                           |
  39.  *---------------------------------------------------------------------------*
  40.  
  41.  This file defines the routines responsible for reading and writing the container TOC. 
  42.  The routines are divided into two main groups as follows:
  43.  
  44.  (1). "Raw" low-level TOC I/O: all the routines to read and write TOC basic value segment
  45.            entries.  These routines format the TOC with the syntatic layout described later in
  46.             this header.
  47.  
  48.            cmStartTOCIO                        -    initiate TOC I/O
  49.             cmEndTOCIO                            - end TOC I/O
  50.             cmFtellTOC                            - get current container TOC I/O "seek" position
  51.             cmFlushTOCOutputBuffer    - write current TOC output buffer
  52.             cmWrite1TOCSegment            - write one value segment
  53.             cmRead1TOCSegment                - read one value segment
  54.                 
  55.  (2). High-level TOC I/O control that determines how to generate or process TOC entries.
  56.             This calles the group (1) routines.
  57.             
  58.             cmBuildGlobalNameTable    - add a global name to the global name table
  59.             cmReadTOC                                - read (laod) in a container TOC
  60.             cmWriteTOC                            - write a TOC to the container
  61.             cmDoBackPatches                    - back patch certain TOC entries
  62. */
  63.  
  64. #ifndef __TOCIO__
  65. #define __TOCIO__
  66.  
  67. #ifndef __CMTYPES__
  68. #include "CMTypes.h"
  69. #endif
  70. #ifndef __CM_API_TYPES__
  71. #include "CMAPITyp.h"
  72. #endif
  73. #ifndef __GLOBALNAMES__
  74. #include "GlbNames.h"   
  75. #endif
  76. #ifndef __CONTAINEROPS__
  77. #include "Containr.h"  
  78. #endif
  79. #ifndef __TOCENTRIES__
  80. #include "TOCEnts.h"   
  81. #endif
  82.  
  83.                                                                         CM_CFUNCTIONS
  84.  
  85. #if TOC1_SUPPORT
  86.                                                 /*-------------------------------------*
  87.                                                  | Defined "Old" Layout of a TOC Entry |
  88.                                                  *-------------------------------------*
  89.  
  90. As defined by the original API documentation, a container TOC entry has the following
  91. layout:
  92.  
  93.       0           4           8           12          16          20    22    24
  94.          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  95.          | Object ID |Property ID|  Type ID  |Valu Offset| Value Len | Gen |Flags|
  96.          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  97.                4           4           4           4           4        2     2
  98.  
  99. These are defined as "hard-coded" constants since the format is, by definition, platform
  100. independent.  The actual formatting and I/O for a TOC entry is done by a handler because
  101. of this.                                                                                                                                                                */
  102.  
  103. #define TOCentryObjectID          0                /* 4 bytes: the object's ID                                                */
  104. #define TOCentryPropertyID      4                /* 4        its property ID                                                */
  105. #define TOCentryTypeID              8                /* 4        its type ID                                                        */
  106. #define TOCentryValueOffset 12                /* 4        offset to its value                                        */
  107. #define TOCentryValueLength    16                /* 4        size of the value                                            */
  108. #define TOCentryGeneration    20                /* 2        generation number                                            */
  109. #define TOCentryFlags                22                /* 2        flags                                                                    */
  110.                      
  111. #define TOCentrySize                 24                /* defined size of a TOC entry in its container        */
  112.  
  113. /* The following macros allow portable (I hope) access to a TOC's entry fields.  There     */
  114. /* are two sets of macros; one set for input, and one for output.  Each set consists of    */
  115. /* two definitions; one when using buffered I/O and the other when calling a handler        */
  116. /* directly.  The code is configurable (CMConfig.h) to do either.  But in some cases        */
  117. /* we ignore the configuration, so all definitions must be defined here.  The goal here */
  118. /* is to define in THIS ONE PLACE all the dependencies on the actual TOC format.  If it    */
  119. /* changes, then theoritically all we need to do is change this stuff here.  Cross your    */
  120. /* fingers!                                                                                                                                                            */
  121.  
  122. /* The first pair of macros are for extracting the TOC fields.  In the buffered case the*/
  123. /* fields are extracted directly out of the buffer.  In the nonbuffered case, the buffer*/
  124. /* is supplied to the macro to extract the fields.                                                                            */
  125.  
  126. #define BufferedExtractTOC(ioBuffer, objectID, propertyID, typeID, value, valueLen, generation, flags) \
  127.                     {objectID      = (CM_ULONG)GET4(ioBuffer);    \
  128.                      propertyID = (CM_ULONG)GET4(ioBuffer);    \
  129.                      typeID          = (CM_ULONG)GET4(ioBuffer);    \
  130.                      value          = (CM_ULONG)GET4(ioBuffer);    \
  131.                      valueLen     = (CM_ULONG)GET4(ioBuffer);    \
  132.                      generation = (CM_USHORT)GET2(ioBuffer);    \
  133.                      flags            = (CM_USHORT)GET2(ioBuffer);}
  134.  
  135. #define ExtractTOC(tocBuffer, objectID, propertyID, typeID, value, valueLen, generation, flags) \
  136.                     {CMextractData(container, (char *)tocBuffer + TOCentryObjectID,      4, &objectID);            \
  137.                      CMextractData(container, (char *)tocBuffer + TOCentryPropertyID,  4, &propertyID);        \
  138.                      CMextractData(container, (char *)tocBuffer + TOCentryTypeID,          4, &typeID);                \
  139.                      CMextractData(container, (char *)tocBuffer + TOCentryValueOffset, 4, &value);                \
  140.                      CMextractData(container, (char *)tocBuffer + TOCentryValueLength, 4, &valueLen);            \
  141.                      CMextractData(container, (char *)tocBuffer + TOCentryGeneration,  2, &generation);        \
  142.                      CMextractData(container, (char *)tocBuffer + TOCentryFlags,            2, &flags);}
  143. #endif
  144.  
  145.                                                 /*-------------------------------------*
  146.                                                  | Defined "New" Layout of a TOC Entry |
  147.                                                  *-------------------------------------*
  148.  
  149. The TOC in the container has the following syntatic layout:
  150.  
  151.                                                  --                        --   
  152.                                                    |  ( PT [g] [R] v... )     |   
  153.                           { OPT [g] [R] v... |  <                 > ... | } ...
  154.                                                    |  ( T  [g] [R] v... )     |   
  155.                                                  --                        --   
  156.                                                     
  157. where OPT = object entry (NewObject code plus 4-byte object, property, and type ID)
  158.             PT  = property entry (NewProperty code plus 4-byte property and type ID)
  159.             T   = type entry (newType plus 4-byte type ID)
  160.             g   = optional generation number if different from previous generation number
  161.           R      = object ID of value's references recording object (if any)
  162.             v   = value entry (code plus offset/length or 4-byte immediate) -- code determines
  163.                         4 or 8 byte offsets and actual size of immediate
  164.                         
  165. In other words, nothing is repeated if it doesn't change.  The 4-byte data entries are
  166. preceded by byte codes defined as follows:                                                                                            
  167.                                                                                                                                                               Bytes        */
  168. /*      Code                                                          Meaning                                                           Consumed    */
  169. /*======================================================================================*/
  170. #define NewObject                      1U                    /* object + property + type                                    12         */
  171. #define NewProperty                  2U                    /* property + type                                                     8         */
  172. #define NewType                          3U                    /* type                                                                          4         */
  173. #define ExplicitGen                 4U                    /* generation                                                                 4         */
  174. #define Offset4Len4                  5U                    /* 4-byte offset + 4-byte length                         8         */
  175. #define ContdOffset4Len4     6U                    /* continued 4-byte offset + 4-byte length     8         */
  176. #define Offset8Len4                  7U                    /* 8-byte offset + 4-byte length                        12         */
  177. #define ContdOffset8Len4     8U                    /* continued 8-byte offset + 4-byte length    12         */
  178. #define Immediate0                 9U                    /* immediate (length = 0)                                         0         */
  179. #define Immediate1                10U                    /* immediate (length = 1)                                         4         */
  180. #define Immediate2                11U                    /* immediate (length = 2)                                         4         */
  181. #define Immediate3                12U                    /* immediate (length = 3)                                          4         */
  182. #define Immediate4                13U                    /* immediate (length = 4)                                          4         */
  183. #define ContdImmediate4        14U                    /* continued immediate (length = 4)                     4         */
  184. #define ReferenceListID        15U                    /* references recording object ID                         4        */
  185. #define Reserved4b                16U                    /*     "     "     "    "  "  "   "    "         4        */
  186. #define Reserved4c                17U                    /*     "     "     "    "  "  "   "    "         4        */
  187. #define Reserved8a                18U                    /* reserved for future use of 8 byte entry     8        */
  188. #define Reserved8b                19U                    /*     "     "     "    "  "  "   "    "         8        */
  189. #define Reserved8c                20U                    /*     "     "     "    "  "  "   "    "         8        */
  190. #define Reserved12a                21U                    /* reserved for future use of 12 byte entry    12        */
  191. #define Reserved12b                22U                    /*     "     "     "    "  "   "   "    "        12        */
  192. #define Reserved12c                23U                    /*     "     "     "    "  "   "   "    "        12        */
  193. #define EndOfBufr                    24U                    /* end of current buffer, go to next                  0        */
  194. /*======================================================================================*/
  195.  
  196. /* The following define special codes and values related to the above TOC codes:                */
  197.  
  198. #define FirstCode                     1U        /* lowest code used (see notes below)                                        */
  199. #define LastCode                 24U        /* highest code used (see notes below)                                    */
  200.  
  201. #define NOP                         0xFFU        /* NOP or filler                                                                                 */
  202. #define TOCEOF                 0x00U        /* EOF signal code only returned for TOC input                    */
  203.                                                                                                                                                                                 /*
  204. Notes: 1. The TOCEOF code is NOT a code placed in the TOC.  It is used only reading the
  205.                     TOC to signal that all TOC bytes have been read.
  206.              
  207.              2. The codes form a dense set starting at 1 (FirstCode) and extend up to LastCode.
  208.                    This is done to allow the definition arrays associated with the codes using the
  209.                     following typedef:                                                                                                                        */
  210.                     
  211.                   typedef unsigned char TOCCodeArray[LastCode+1];
  212.                                                                                                                                                                                  /*
  213.              3. One use of the codes and the code array is to define the size of the data 
  214.                      associated with each code.  To keep the size info in proximity with the above
  215.                     definitions (to make it easier for changing), the following macro is defined to
  216.                     init an entry size array to the proper size for each code:                                        */
  217.  
  218.                     #define InitCodeSizes(entrySizeArray)    entrySizeArray[NewObject       ]    =    12;    \
  219.                                                                                                 entrySizeArray[NewProperty     ]    =     8;    \
  220.                                                                                                 entrySizeArray[NewType         ]    =     4;    \
  221.                                                                                                 entrySizeArray[ExplicitGen     ]    =     4;    \
  222.                                                                                                 entrySizeArray[Offset4Len4     ]    =     8;    \
  223.                                                                                                 entrySizeArray[ContdOffset4Len4]    =     8;    \
  224.                                                                                                 entrySizeArray[Offset8Len4     ]    =    12;    \
  225.                                                                                                 entrySizeArray[ContdOffset8Len4]    =    12;    \
  226.                                                                                                 entrySizeArray[Immediate0      ]    =     0;    \
  227.                                                                                                 entrySizeArray[Immediate1      ]    =     4;    \
  228.                                                                                                 entrySizeArray[Immediate2      ]    =     4;    \
  229.                                                                                                 entrySizeArray[Immediate3      ]    =     4;    \
  230.                                                                                                 entrySizeArray[Immediate4      ]    =     4;    \
  231.                                                                                                 entrySizeArray[ContdImmediate4 ]    =     4;    \
  232.                                                                                                 entrySizeArray[ReferenceListID ]    =     4;    \
  233.                                                                                                 entrySizeArray[Reserved4b      ]    =     4;    \
  234.                                                                                                 entrySizeArray[Reserved4c      ]    =     4;    \
  235.                                                                                                 entrySizeArray[Reserved8a      ]    =     8;    \
  236.                                                                                                 entrySizeArray[Reserved8b      ]    =     8;    \
  237.                                                                                                 entrySizeArray[Reserved8c      ]    =     8;    \
  238.                                                                                                 entrySizeArray[Reserved12a     ]    =    12;    \
  239.                                                                                                 entrySizeArray[Reserved12b     ]    =    12;    \
  240.                                                                                                 entrySizeArray[Reserved12c     ]    =    12;    \
  241.                                                                                                 entrySizeArray[EndOfBufr         ]    =     0
  242.                                                                                                                                                                                 /*
  243.              4. All data entry sizes are a multiple of 4.  Thus data values are passed around
  244.                      in (unsigned) long variables.  Therefore, in terms of long variables, a maximum
  245.                     of 12/4 longs would be needed to hold the largest value according to the above
  246.                     sizes.                                                                                                                                                */
  247.  
  248.                     #define MaxEntrySize (12/4)                        /* max nbr of longs to hold entry data    */
  249.                                                                                                                                                                                 /*
  250.              5. In general, ignoring immediates, a value segment takes a minimum of 8 bytes.    
  251.                    Thus, when maintaining the free list, we should not add anything to that list
  252.                     if it is less than 8 plus 1 for the entry code.                                                                */
  253.                     
  254.                     #define MinTOCSize (1+8)                            /* assumed min TOC entry size                        */
  255.  
  256. /* The following defines all the information associated with a single TOC value data         */
  257. /* segment.  It is clustered as a struct to make it easier to "carry around".                     */
  258.  
  259. struct TOCentry {                                            /* Place to put a TOC entry during its write:            */
  260.     CM_ULONG           objectID;                        /*         the object's ID                                                            */
  261.     CM_ULONG           propertyID;                    /*         an object's property ID                                            */
  262.     CM_ULONG           typeID;                            /*         an object's type ID                                                    */
  263.     TOCValueBytes  value;                                /*         value and length or immediate value                    */
  264.     CM_ULONG           generation;                    /*         generation number                                                        */
  265.     CM_USHORT             flags;                                /*         object flags                                                                */
  266. };
  267. typedef struct TOCentry TOCentry, *TOCentryPtr;
  268.  
  269. struct TOCEntryListItem {                            /* So that we can put TOCEntry in a list                    */
  270.     ListLinks                tocEntryLinks;            /*     links to nex/prev toc entry                                        */
  271.     TOCentry                tocEntryItem;                /*     the toc entry                                                                    */
  272.     CM_ULONG              refsDataObjectID;        /*     reference object id                                                        */
  273. };
  274. typedef struct TOCEntryListItem TOCEntryListItem, *TOCEntryListItemPtr;
  275.  
  276. enum TocEntryType {                                    /* Select what TOC entries to read:    */
  277.     TocEntry_All,                                                /*        read everything                                                            */
  278.     TocEntry_Update,                                        /*        only the update entries                                         */
  279.     TocEntry_NewEntry                                        /*        the new additions to the TOC                                */
  280. };
  281. typedef enum TocEntryType TocEntryType;
  282.  
  283. /* In some cases, when the TOC is written, it is necessary to backpatch certain entries    */
  284. /* because we don't know the information when the entry is initially written.  The             */
  285. /* following defines "BackPatches" area used to remember what has to be back patched and*/
  286. /* the corresponding container offsets that will get the back patch.  These will always    */
  287. /*( be offsets to the value of the value/length fields in the TOC.                                            */
  288.  
  289. struct BackPatches {                                    /* All the info on all possible patches:                    */
  290.     CM_USHORT             whatWeGot;                        /*        flags indicating upatched entries we got        */
  291.     CM_ULONG             tocSizeEntry;                /*        offset to TOC #1 size value                                    */
  292.     CM_ULONG             tocContEntry;                /*        offset to TOC #1 container value                        */
  293.     CM_ULONG             tocNewValuesTOCEntry;/*        offset to TOC #1 new values TOC value                */
  294. };
  295. typedef struct BackPatches BackPatches, *BackPatchesPtr;
  296.  
  297. #define Patch_TOCsize                  0x0001U    /* indicates tocSizeEntry created                                    */
  298. #define Patch_TOCContSize          0x0002U    /* indicates tocContEntry created                                    */
  299. #define Patch_TOCNewValuesTOC 0x0004U    /* indicates tocNewValuesTOCEntry created                    */
  300.  
  301. #define InitBackPatches(patches) (((BackPatchesPtr)(patches))->whatWeGot = 0x0000U)
  302.     /*
  303.     This macro is used to init the back-patches data prior to writing TOC(s).  The macro 
  304.     takes a pointer to a BackPatches struct.
  305.     */
  306.  
  307.  
  308. void *cmStartTOCIO(ContainerPtr container, CM_ULONG tocBufSize, jmp_buf *ioEnv,
  309.                                      CM_ULONG tocOffset, CM_ULONG tocSize);
  310.     /*
  311.     This must be called prior to any reading or writing of the TOC.  The basic standard
  312.     protocol to be followed is as follows:
  313.     
  314.      if (setjmp(env)) {
  315.          <caller's recovery and exit>
  316.      }
  317.      
  318.      CMseek(to proper TOC position in the container);
  319.      
  320.      t = cmStartTOCIO(container, container->tocBufSize, (jmp_buf *)&env, tocOffset, tocSize);
  321.      
  322.                             when reading                  or          when writing
  323.                             ------------                              ------------
  324.      
  325.              while (cmRead1TOCSegment(t, ...)) {   |   some kind loop through the TOC
  326.                  cmRead1TOCSegment(t, ...);          |   {
  327.                  <process TOC entry>                 |             <set up TOC entry>
  328.              }                                     |      cmWrite1TOCSegment(t, ...);
  329.                                                                                          |   }
  330.                                                                                          |   cmFlushTOCOutputBuffer(t, true);
  331.      cmEndTOCIO(t);
  332.     
  333.     The TOC to be read or written is assumed to start at the specified tocOffset. It is the
  334.     caller's responsibility to seek to this position.  For reading a TOC, tocSize defines the
  335.     EXACT amount of TOC to be read.  For writing, tocSize must be passed as 0. The final size
  336.     will be returned when endTOCIO() is called to terminate TOC creation (alternatively,
  337.     cmFlushTOCOutputBuffer() will return the final size).
  338.      
  339.     cmStartTOCIO() allocates an I/O buffer and its associated control information. The buffer
  340.     is used to format or extract TOC entries.  The TOC I/O control block pointer allocated is
  341.     returned as the function result as an anonymous "void *" pointer.  This is passed to all
  342.     the other low level TOC externalized buffering routines (cmWrite1TOCSegment(),
  343.     cmread1TOCSegment(), cmFlushTOCOutputBuffer(), cmFTellTOC(), and endTOCIO()).  An error
  344.     is reported for allocation errors.  If the error reporter returns, NULL is returned as
  345.     the function result.
  346.     
  347.     The maximum size of the buffer to be allocated is passed.  This will generally be
  348.     determined from the container label, but that is not assumed here.  The size is, however,
  349.     always ensured to be rounded up to a multiple of 4.
  350.     
  351.     A set setjmp/longjmp environment variable is also passed for read and write error
  352.     reporting and recovery.  The setjmp/longjmp is used rather than have to check for errors
  353.     on each I/O call of the buffered I/O routines.  If the longjmp is taken, the caller can
  354.     assume that the appropriate error has been reported and the buffer and its control block
  355.     freed.
  356.      
  357.     Note, in the case of updating, the private TOC and the non-private (updating) TOC are
  358.     viewed as two INDEPENDENT TOCs.  There is no need to worry that the non-private (i.e.,
  359.     second TOC) does not start on a buffer boundary with respect to the private (first) TOC.
  360.     Each is read or written independently and viewed as distinct from one another.  They just
  361.     happen to be adjacent to one another in the container.  The tocBufSize and tocOffset
  362.     must be appropriately passed for each TOC.
  363.     
  364.     Also note, that the reason some of the low level buffering routines have been made
  365.     external (cmWrite1TOCSegment(), cmread1TOCSegment(), cmFlushTOCOutputBuffer(), 
  366.     cmFTellTOC(), and endTOCIO()) is to mainly allow for the debugging trace routines to read
  367.     the TOC.  cmWrite1TOCSegment() and cmFlushTOCOutputBuffer() are external only for
  368.     symmetry, but it should have no external callers (i.e., they're all in this file).  
  369.     Making these routines externally visable is also why the I/O control block pointer is
  370.     returned as an anonymous "void *".
  371.     */
  372.     
  373.  
  374. CM_ULONG cmEndTOCIO(void *tocIOCtl);
  375.     /*
  376.     After all I/O to a TOC is completed, this routine must be called to free the TOC I/O
  377.     buffer and control block (whose pointer is passed as the t parameter).  If the TOC was
  378.     created (written), then it is assumed the last buffer was already flushed by calling
  379.     flushTOCOutputBuffer() with its finalFlush parameter set to true. 
  380.     
  381.     The function returns the size of the TOC.  For TOC creation (writing), this will be the
  382.     size of the TOC now written to the container.  For reading, the returned value is 
  383.     identical to the size passed to cmStartTOCIO() (i.e., the returned value is not looked at
  384.     for reading).
  385.     
  386.     Note, this routine must NOT be called if an error was reported and the longjmp taken 
  387.     through the setjmp environment buffer passed to cmStartTOCIO()>  Part of standard error
  388.     recovery for TOC I/O errors is effectively do a cmEndTOCIO() and then report the error.
  389.     If the error reporter returns, the longjmp is taken.
  390.     */
  391.  
  392.  
  393. CM_ULONG cmFtellTOC(void *tocIOCtl);
  394.     /*
  395.     This returns the current container I/O position.  The position is updated as the TOC I/O
  396.     buffer fills and is written or reloaded when reading.
  397.     
  398.     This routine is needed when only when there is the possibility that other code might be
  399.     doing "seeks" to the same container behind the TOC I/O routine's back!  Code doing such
  400.     seeks must be able to reseek the container position according to the value returned here.
  401.     */
  402.  
  403.  
  404. CM_ULONG cmFlushTOCOutputBuffer(void *tocIOCtl, CMBoolean finalFlush);
  405.     /*
  406.     This must be called to make sure that the TOC output buffer (allocated by cmStartTOCIO()
  407.     and associated with tocIOCtl) is flushed, i.e., fully written.  This buffer will be the
  408.     remaining partial buffer when finalFlush is true, and a full buffer otherwise.  The 
  409.     buffer is padded if necessary up to the full buffer size (defined by cmStartTOCIO()) or
  410.     to the nearest multiple of 4 when finalFlush is true.  finalFlush would, of course, only
  411.     be true prior to calling cmEndTOCIO() to write the LAST buffer out as a "short" buffer.
  412.     
  413.     Padding consists of a EndOfBufr byte followed by 0 or more NOP bytes.  Padding is not
  414.     necessary, of course, if the buffer is exactly full.
  415.  
  416.   The function returns the current total size of the TOC including the flushed buffer. This
  417.   generally has no meaning until finalFlush is true, at which time the returned amount will
  418.   be the total size of the TOC written to the container. 
  419.     */
  420.  
  421.  
  422. CM_ULONG cmWrite1TOCSegment(void *tocIOCtl,
  423.                                                         CM_ULONG  objectID, 
  424.                                                         CM_ULONG  propertyID, 
  425.                                                         CM_ULONG  typeID,
  426.                                                         CM_ULONG  value,
  427.                                                         CM_ULONG  valueLen,
  428.                                                         CM_ULONG  generation,
  429.                                                         CM_USHORT flags,
  430.                                                         TOCObjectPtr     refDataObject);
  431.     /*
  432.     All TOC value segment writing is done with this routine.  This routine interfaces the
  433.     low-level TOC entry buffering routines (whose I/O control block is associated with
  434.     tocIOCtl and allocated by cmStartTOCIO()) with the upper-level writers.  The upper level
  435.     (i.e., the caller) views all value segments in terms of the fields shown as this
  436.     routine's parameters.  Here that information is selectively passed to the lower-level
  437.     buffering routines to generate a TOC in the container with the syntactic layout described
  438.     above.  
  439.     
  440.     Since this syntax describes a TOC layout where nothing is repeated if it doesn't change,
  441.     this routine remembers and controls what goes out and when.  Note that, at a minimum, a
  442.     data value (v) is always generated.
  443.  
  444.   Note the refDataObject parameter represents the "R" in the syntax.  refDataObject is a
  445.   pointer to a value's private reference recording object ID.  This is the value's private
  446.   object used to hold the list of CMReference "key"/object ID associations as value data.
  447.   If refDataObject is NULL no "R" is generated.  If not NULL we generate the ID after the
  448.   OPT, PT, or T.  
  449.  
  450.     The function returns the container offset to the value entry entry data (v).  This can
  451.     be remembered by the higher-level caller for possible back patching later.
  452.     
  453.     Note, no consistency checking is done here. It is assumed all error checks have been done
  454.     by the caller, and that by the time this routine is called, it is EXPECTED that a TOC
  455.     entry will be created.  I/O errors can, of course, occur.  They use the setjmp/longjmp
  456.     mechanism defined by cmStartTOCIO().
  457.     */
  458.     
  459.  
  460. CMBoolean cmRead1TOCSegment(void *tocIOCtl,
  461.                                                         TOCentry  *tocEntry, 
  462.                                                         CM_ULONG  *refsDataObjectID);
  463.     /*
  464.     All TOC value segment reading is done with this routine.  This routine interfaces the
  465.     low-level TOC entry buffering routines (whose I/O control block is associated with
  466.     tocIOCtl and allocated by cmStartTOCIO()) with the upper-level writers.  The upper level
  467.     (caller) views all value segments in terms of the fields shown as this routine's
  468.     parameters.  
  469.     
  470.     The container TOC has the syntactic layout described above.  Since this syntax describes
  471.     a TOC layout where nothing is repeated if it doesn't change, this routine remembers the
  472.     unrepeated information are repeats it back to the caller.
  473.  
  474.     The function always returns true until an "eof" is detected, i.e., until all the bytes, 
  475.     whose size was specified to cmStartTOCIO(), are read.  False is returned for the "eof".
  476.  
  477.     Note, refsDataObjectID represents a value's private reference recording object ID.  This
  478.     is the value's private object used to hold the list of CMReference "key"/object ID
  479.     associations as value data.  0x00000000UL is returned in refsDataObjectID if there is no
  480.     recording object and, of course, will be the object ID if it is.
  481.     */
  482.  
  483.  
  484. CMBoolean cmBuildGlobalNameTable(TOCValuePtr theValue);
  485.     /*
  486.      This routine creates a global name symbol table entry for each value that has a property
  487.      ID that indicates the value is for a global name.
  488.      
  489.      When a TOC is read in from a container we must build up our memory structures exactly as
  490.      they were when the container was previously written.  That means that, in addition to the
  491.      TOC data structures, we have to build the global name symbol table containing the global
  492.      name strings for those values. Thus is routine is ONLY called during read-in (and only
  493.      from cmAppendValue()).  At that time the switch tocFullyReadIn is false, which is a status
  494.      switch indicating the TOC read is not yet complete.
  495.      
  496.      A word of caution!  Remember that this routine is only called during read in of a TOC. But
  497.      here we must read in a global name.  That will CHANGE the current "seek" position of the
  498.      next read.  cmReadTOC(), which is the routine that does the TOC reading, always keeps its
  499.      current TOC offset (the one just read) in tocInputOffset in the container.  We use that to
  500.      re-seek so that cmReadTOC() is none the wiser.
  501.     */
  502.     
  503.     
  504. CMBoolean cmReadTOC(ContainerPtr container, TocEntryType whichKind, 
  505.                                         CM_ULONG tocOffset, CM_ULONG tocSize,
  506.                                         ListHdr *newEntryList);
  507.     /*
  508.     This routine is called to read in a TOC from a container which has been opened for input
  509.     by a call to CMOpenContainer().  The container, offset to TOC, and the size of the TOC
  510.     are passed.  The function returns true if successfully loaded and false otherwise (this
  511.     is a safety, since error reports should never return from the error handler).
  512.     
  513.     Note, the entire TOC whose size is defined by tocSize will be read.  It is an error if
  514.     not all the bytes are read.  This means that it is expected that tocSize be the EXACT 
  515.     amount to read from tocOffset.  This is emphasized because, for updating, two TOCs must
  516.     be read; the private TOC, and the non-private (updating) TOC.  The private offset and
  517.     size are defined in the container label (by definition).  For non-updating containers,
  518.     this will reflect the entire (only) TOC.  The non-private (updating) portion is defined
  519.     by a TOC #1 property.
  520.     
  521.     WhichKind controls what kind of entry will be read. This is because we need to read in the
  522.     update entry first because they may contains deletion, then we read in the rest, otherwise the
  523.     newly read entries may be deleted.
  524.     
  525.     When whickKind is TocEntry_Update, pass in an initialized but empty list so that the
  526.     newEntry may be collected. Later when cmReadTOC is called again for the new entries,
  527.     pass in the same newEntryList to avoid reading the TOC again fro the new entries.
  528.     */
  529.  
  530.  
  531. CMBoolean cmWriteTOC(ContainerPtr container, void *toc, CMObjectID startingID,
  532.                                          CMObjectID endingID, BackPatchesPtr thePatches,
  533.                                          CM_ULONG *tocStart, CM_ULONG *tocSize,
  534.                                          CMBoolean truncFreeSpace);
  535.     /*
  536.     This routine is the inverse to cmReadTOC() to write the in-memory TOC to a container. The
  537.     TOC is written to the end of the container.  Only objects with ID's greater than or equal
  538.     to the startingID and less than or equal to the endingID are written.  Further, only
  539.     objects whose value headers are equal to the specified container are written.
  540.     
  541.     With the restriction on the container, we will only write to the TOC newly created values
  542.     for this open session.  If we're not updating, only one container so this is not an
  543.     issue.  But for updating, only looking at the stuff in the updating container will yield
  544.     all new objects and all new properties for "old" objects.  We can split these two groups
  545.     using the ID limits.
  546.     
  547.     Note, non-TOC updates are generated by a separate walk not done here.  See Updating.c.
  548.     
  549.     For updating, a container may have its own TOC and the target TOC.  Thus the TOC pointer
  550.     is an explicit parameter.  The container offset is returned in tocStart and the size of
  551.     the TOC in tocSize.  The function returns true to indicate success and false otherwise
  552.     (as a safety).
  553.     
  554.     There are some TOC entries that must be back-patched. This is because they are a function
  555.     of the final TOC size in the container.  We don't know that until the entire TOC is
  556.     written.  At that time we can rewrite the entries with the proper values filled in.
  557.     
  558.     Because of updating, there may be multiple calls to cmWriteTOC() to write various subsets
  559.     of the TOC (i.e., the updates).  Thus we may not know the final TOC size when we return
  560.     from here.  The back-patching cannot be done.  Only the caller knows when all TOC writes
  561.     are complete and the back-patching can be done.
  562.     
  563.     To allow this to happen, thePatches is passed as a pointer to a BackPatches struct where
  564.     we save the original unpatched TOC info and offset for the entries of interest.  As these
  565.     entries are encountered (and they must be sometime) during TOC writing, we save them and
  566.     their offsets in the struct. When the caller is ready to rewrite them cmDoBackPathes() is
  567.     called to do it.
  568.     
  569.     If thePatches is passed as NULL, nothing (obviously) is saved for back-patching.
  570.     */
  571.  
  572.  
  573. CMBoolean cmDoBackPatches(ContainerPtr container, BackPatchesPtr thePatches,
  574.                                                   CM_ULONG tocStart, CM_ULONG tocSize,
  575.                                                     CM_ULONG newValuesTOCStart, CM_ULONG newValuesTOCSize);
  576.     /*
  577.     When a TOC is written (e.g., cmWriteTOC()), there are some entries that are dependent on
  578.     the final size of the TOC.  Such entries must be back-pached with the proper info.  Only
  579.     the callers generating the TOC in the container know when it is time to do the patching.
  580.     They call this routine to do it when that time comes.
  581.     
  582.     True is returned if the back-patching is successful and false otherwise.
  583.     
  584.     By the time this routine is called, the original TOC entries in question and their
  585.     offsets within the container have been recorded in a BackPatches struct whose pointer is
  586.     passed in thePatches.  Currently only 3 such entries need back-patching:
  587.     
  588.     tocSizeEntry                  -    The TOC size entry.  This is a property of TOC #1 which
  589.                                                     represents the size and offset of the TOC itself.  The caller
  590.                                                     passes this info in the tocSize and tocStart parameters
  591.                                                     respectively.
  592.                                             
  593.     tocContEntry                  -    The TOC container entry. This is a property of TOC #1 which
  594.                                                     represents the entire container, from offset 0 to the end of the
  595.                                                     label.  No additional parameters are passed for this.  But to
  596.                                                     compute this, it is required that cmDoBackPathes() be the LAST
  597.                                                     thing called prior to writing the container label.
  598.      
  599.     tocNewValuesTOCEntry - The non-private TOC offset/size entry.  An updating TOC contains
  600.                                                  a TOC #1 property that defines the offset and size of all TOC
  601.                                                  entries that are to be applied to this container's target.  The
  602.                                                  caller passes this info in the newValuesTOCSize and
  603.                                                  newValuesTOCStart parameters respectively.  For non-updating
  604.                                                  containers, these are ignored.
  605.     */
  606.  
  607.  
  608.                                                           CM_END_CFUNCTIONS
  609. #endif
  610.